package org.gaaidou.ptarmigan.springboot.core.common;

import lombok.extern.slf4j.Slf4j;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
public final class BeanMapUtil {
    private BeanMapUtil() {
        // nothing to do
    }


    public static void copyMapToBeanNoGeneric(Map<?, ?> source, Object target) {
        Map<String, Object> newMap = initNewMap(source);
        copyMapToBean(newMap, target);
    }


    public static void copyMapToBean(Map<String, Object> source, Object target) {
        Field[] declaredFields = target.getClass().getDeclaredFields();
        Map<String, Field> methodMap = Arrays.stream(declaredFields).collect(Collectors.toMap(declaredField -> declaredField.getName().toUpperCase(), declaredField -> declaredField, (a, b) -> b));
        source.forEach((key, value) -> {
            if (null != value && methodMap.containsKey(key) && methodMap.get(key).getType().isInstance(value)) {
                try {
                    PropertyDescriptor pd = new PropertyDescriptor(methodMap.get(key).getName(), target.getClass());
                    Method method = pd.getWriteMethod();
                    method.invoke(target, value);
                } catch (Exception e) {
                    log.warn("Map转Bean失败, 字段名称: {}, 值: {}, 异常原因: {}", key, value, e.getMessage());
                }
            }
        });
    }


    private static Map<String, Object> initNewMap(Map<?, ?> map) {
        Map<String, Object> newMap = new HashMap<>(map.size());
        map.forEach((k, v) -> newMap.put(FormatUtil.lineToHump(k.toString()).toUpperCase(), v));
        return newMap;
    }


}
